package regulatoryInteractionsStats.yeast.bioJava;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import utils.FileUtils;

/**
 *
 * @author jamie
 */
public class AlignmentParser {

    private final File inputAlignmentFile = new File("/Users/jamie/Documents/work/biclustering/alignments.txt");
    private static final File outputAlignmentFile_global = new File("/Users/jamie/Documents/work/biclustering/alignmentsSummary_global.txt");
    private static final File outputAlignmentFile_local = new File("/Users/jamie/Documents/work/biclustering/alignmentsSummary.txt");
    private final BufferedWriter writer_local = FileUtils.getBufferedWriter(outputAlignmentFile_local);
    private final BufferedWriter writer_global = FileUtils.getBufferedWriter(outputAlignmentFile_global);
    private int noOfAlignments = 0;

    public AlignmentParser(boolean local) {
        local = true;
        parseFile(inputAlignmentFile, local);
        getAlignmentsHash(local);

    }

    public int getNoOfAlignments() {
        return noOfAlignments;
    }

    public File getOutputLocalAlignmentFile() {
        return outputAlignmentFile_local;
    }

    public File getOutputGlobalLocalAlignmentFile() {
        return outputAlignmentFile_local;
    }

    private void closeWriter(boolean local) {
        if(local){
            try {
                writer_local.close();
            } catch (IOException ex) {
                Logger.getLogger(AlignmentParser.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            try {
                writer_global.close();
            } catch (IOException ex) {
                Logger.getLogger(AlignmentParser.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private int getMatches(String line) {
        int counter = 0;
        char chars[] = line.toCharArray();
        for (char c : chars) {
            if (c == '|') {
                counter++;
            }
        }
        return counter;
    }

    private boolean output(MyAlignment a, boolean local) {
        String out = a.getKey() + "\t" + a.getAccession1() + "\t" + a.getAccession2() + "\t" + a.getLength1() + "\t" + a.getLength2() + "\t" + a.getAlignmentLength() + "\t" + a.getScore() + "\t" + a.getIdentity()+"\n";
//        MyAlignment aln = new MyAlignment();
//        String split[] = out.split("\t");
//        try {
//            aln.setKey(split[0]);
//            aln.setAccession1(split[1]);
//            aln.setAccession2(split[2]);
//            aln.setLength1(Integer.parseInt(split[3]));
//            aln.setLength2(Integer.parseInt(split[4]));
//            aln.setAlignmentLength(Integer.parseInt(split[5]));
//            aln.setScore(Double.parseDouble(split[6]));
//            aln.setIdentity(Integer.parseInt(split[7]));
//
//        } catch (Exception ex) {
//            System.out.println(out+"\n");
//            System.out.flush();
//            ex.printStackTrace();
//            return true;
//        }
        try {
            if(local){
                writer_local.append(out);
                writer_local.flush();
            }else {
                writer_global.append(out);
                writer_global.flush();
            }
        } catch (IOException ex) {
            Logger.getLogger(AlignmentParser.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    private void parseFile(File alignmentFile, boolean local) {
        BufferedReader reader = FileUtils.getBufferedReader(alignmentFile);
        String line;
//        StringBuffer alnBuffer = new StringBuffer();
        try {
            MyAlignment currentAlignment = null;
            int nextDataLine = 0;
            int currentScore = 0;
            while ((line = reader.readLine()) != null) {
//                alnBuffer.append(line+"\n");
                line.trim();
                String split[] = line.split("\t");
                if (split[0].contains("Time (ms)")) {
                    if (currentAlignment != null) {
                        currentAlignment.setIdentity(currentScore);

                        boolean wtf = output(currentAlignment.myclone(), local);
//                        if (wtf) {
//                            System.out.println(alnBuffer.toString());
//                        }
//                        alnBuffer = new StringBuffer();
                        noOfAlignments++;

                        currentScore = 0;
                    } else {
                        currentAlignment = new MyAlignment();

                    }
                    nextDataLine = 1;
                } else if (nextDataLine == 1) {
                    currentAlignment.setAlignmentLength(Integer.parseInt(split[1]));
                    nextDataLine = 2;
                } else if (nextDataLine == 2) {
                    currentAlignment.setScore(Double.parseDouble(split[1]));
                    nextDataLine = 3;
                } else if (nextDataLine == 3 || nextDataLine == 4) {
                    String accession = split[1].replace(",", "");
                    accession.trim();
//                    System.out.println(split[3]);


                    int length = Integer.parseInt(split[3]);

                    if (nextDataLine == 3) {
                        currentAlignment.setAccession1(accession);
                        currentAlignment.setLength1(length);
                        nextDataLine = 4;
                    } else {
                        currentAlignment.setAccession2(accession);
                        currentAlignment.setLength2(length);
                        nextDataLine = 0;
                    }

                } else if (nextDataLine == 0) {
                    int matches = getMatches(line);
                    currentScore += matches;
                }

            }
            currentAlignment.setIdentity(currentScore);
            output(currentAlignment.myclone(), local);
            noOfAlignments++;
            System.out.println("there are " + noOfAlignments);
            closeWriter(local);
        } catch (IOException ex) {
            Logger.getLogger(AlignmentParser.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

    public static HashMap<String, MyAlignment> getAlignmentsHash(boolean local) {
        HashMap<String, MyAlignment> hash = new HashMap<String, MyAlignment>();
        BufferedReader reader = null;
        if(local){
            reader = FileUtils.getBufferedReader(outputAlignmentFile_local);
        } else {
            reader = FileUtils.getBufferedReader(outputAlignmentFile_local);
        }
        
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
//                System.out.println(line);
                MyAlignment a = new MyAlignment();
                String split[] = line.split("\t");
                try {
                    a.setKey(split[0]);
                    a.setAccession1(split[1]);
                    a.setAccession2(split[2]);
                    a.setLength1(Integer.parseInt(split[3]));
                    a.setLength2(Integer.parseInt(split[4]));
                    a.setAlignmentLength(Integer.parseInt(split[5]));
                    a.setScore(Double.parseDouble(split[6]));
                    a.setIdentity(Integer.parseInt(split[7]));
                    hash.put(a.getKey(), a);
                } catch (java.lang.ArrayIndexOutOfBoundsException ex) {
                    System.out.println(line);
                }
            }
            reader.close();
        } catch (IOException ex) {
            Logger.getLogger(AlignmentParser.class.getName()).log(Level.SEVERE, null, ex);
        }

//        System.out.println(hash.size());
        return hash;

    }
}
